#include <iostream>  
#include <cstdio>  
#include <cstring>  
#include <csignal>  
#include <cerrno>  
#include <unistd.h>  
#include <sys/types.h>
#include <sys/wait.h>



int main()
{
    signal(SIGCHLD, SIG_IGN);
    if(fork() == 0)
    {
        // child
        std::cout << "I am child: " << getpid() << ", I'm quitting" << std::endl;
        sleep(6);
        exit(1);
    }
    // father
    while(1);
    return 0;
}


// SIGCHLD
// void handler(int signo)
// {
//     std::cout << "get a signal: " << signo << std::endl;
//     int ret = 0;
//     while((ret = waitpid(-1, NULL, WNOHANG)) > 0)
//         std::cout << "wait child : " << ret << " success" << std::endl;
// }
// 
// int main()
// {
//     signal(SIGCHLD, handler);
//     if(fork() == 0)
//     {
//         // child
//         std::cout << "I am child: " << getpid() << ", I'm quitting" << std::endl;
//         sleep(2);
//         exit(1);
//     }
//     // father
//     while(1);
//     return 0;
// }

// 编译器优化问题

// volatile int flag = 0;
// void handler(int signo)
// {
//     std::cout << "Get a signal: " << signo << std::endl;
//     flag = 1; // 想要退出循环
// }
// 
// int main()
// {
//     signal(2, handler);
//     while(!flag);
// 
//     std::cout << "Process normal quit" << std::endl;
//     return 0;
// }



// 信号集系统调用的使用
// int main()
// {
//     sigset_t blockSet, prevMask;
// 
//     /* Initialize a signal and set to contain SIGINT */
//     sigemptyset(&blockSet);
//     sigaddset(&blockSet, SIGINT);
// 
//     /* Block SIGINT, save previous signal mask */
//     if(sigprocmask(SIG_BLOCK, &blockSet, &prevMask) == -1)
//         perror("sigprocmask1");
// 
//     /* ... Code that should not be interrupted by SIGINT ... */
// 
//     /* Restore previous signal mask, unblocking SIGINT */
//     if(sigprocmask(SIG_SETMASK, &prevMask, NULL) == -1)
//         perror("sigprocmask2");
// }





// 核心转储验证
// int main()
// {
//     std::cout << "I am running..." << std::endl;
//     sleep(3);
//     int a = 5/0;
// 
//     return 0;
// }


// 定时器的使用
// #define BUFFER_SIZE 1024  
// #define TIMEOUT_SECONDS 5  
//   
//   
// // SIGALRM信号的处理函数  
// void handle_sigalrm(int signum) {  
//     std::cout << "Alarm signal received, timeout occurred.\n"; 
//     exit(-1);
// }  
//   
// int main() {  
//     char buffer[BUFFER_SIZE];  
//     ssize_t bytesRead;  
//   
//     // 设置SIGALRM信号的处理器  
//     if (signal(SIGALRM, handle_sigalrm) == SIG_ERR) {  
//         perror("signal");  
//         return -1;
//     }  
//   
//     // 设定定时器  
//     alarm(TIMEOUT_SECONDS);  
//   
//     std::cout << "Enter some text (or wait " << TIMEOUT_SECONDS << " seconds to timeout): " << std::endl;  
//     bytesRead = read(STDIN_FILENO, buffer, BUFFER_SIZE - 1);  
//   
//     // 取消定时器（通常不需要在read之后立即取消，但在这里展示）  
//     alarm(0);  
//     // 如果读取成功，则处理输入  
//     buffer[bytesRead - 1] = '\0';  
//     std::cout << "You entered: " << buffer << std::endl;  
//     
//     return 0;  
// }




// kill() 的使用方法
// int main(int argc, char *argv[])
// {
//     if(argc != 3 || strcmp(argv[1], "--help") == 1)
//     {
//         perror("usageError");
//     }
// 
//     // 获取信号
//     int sig = std::stoi(argv[1] + 1);
// 
//     // 获取pid
//     int pid = std::stoi(argv[2]);
//     int ret = kill(pid, sig);
//     if(sig != 0)
//     {
//         if(pid == -1)
//             perror("kill");
//     }
//     else 
//     {
//         if(pid == 0)
//             std::cout << "Process exists and we can send it a signal" << std::endl;
//         else 
//         {
//             if(errno == EPERM)
//                 std::cout << "Process exits, but we don't have permission to send it a signal" << std::endl;
//             else if(errno == ESRCH)
//                 std::cout << "Process does not exist" << std::endl;
//             else 
//                 perror("kill");
//         }
//     }
//     exit(EXIT_SUCCESS);
// }





// 程序处理函数
// void (*oldHandler)(int);
// 
// oldHandler = signal(SIGINT, newHandler);
// if(oldHandler == SIG_ERR)
//     perror("signal");
// 
// /* Do something else here. During this time, 
//  * if SIGINT is delivered, newHandler will be used to handle the signal */
// if(signal(SIGINT, oldHandler) == SIG_ERR)
//     perror("signal");

// void handler(int sig)
// {
// 	printf("get a signal:%d\n", sig);
// }
// 
// int main()
// {
// 	signal(2, handler); //注册2号信号
// 	while (1)
//     {
// 		printf("hello signal!\n");
// 		sleep(1);
// 	}
// 	return 0;
// }

